package fatworm.query;

import java.util.HashMap;
import java.util.LinkedList;

import fatworm.query.constant.Constant;
import fatworm.query.constant.IntConstant;
import fatworm.query.constant.StringConstant;

public class TupleList {
	
	private LinkedList<HashMap<String, Constant>> list;
	private LinkedList<String> fieldlist;
	private boolean flag;
	private String name;
	
	public TupleList(LinkedList<String> strs) {
		list = new LinkedList<HashMap<String, Constant>>();
		fieldlist = strs;
	}
	
	public void add(Scan s) {
		HashMap<String, Constant> tuple = new HashMap<String, Constant>();
		
		for (int i = 0; i < fieldlist.size(); i++) 
			tuple.put(fieldlist.get(i), s.getVal(fieldlist.get(i)));
		
		list.add(tuple);
	}
	
	public void add(LinkedList<Constant> vallist) {
		HashMap<String, Constant> tuple = new HashMap<String, Constant>();
		
		for (int i = 0; i < fieldlist.size(); i++)
			tuple.put(fieldlist.get(i), vallist.get(i));
		
		list.add(tuple);
	}
	
	public int getSize() {
		return list.size();
	}
	
	public Constant getVal(int index, String name) {
		return list.get(index).get(name);
	}
	
	public int getInt(int index, String name) {
		Constant c = list.get(index).get(name);
		return ((Integer)((IntConstant)c).asJavaVal()).intValue();
	}
	
	public String getString(int index, String name) {
		Constant c = list.get(index).get(name);
		return (String)((StringConstant)c).asJavaVal();
	}
	
	private boolean isOK(HashMap<String, Constant> a, HashMap<String, Constant> b) {
		if (flag && a.get(name).compareTo(b.get(name)) < 0)
			return true;
		
		if (!flag && a.get(name).compareTo(b.get(name)) > 0)
			return true;
		
		return false;
	}
	
	private void sort(int s, int e) {
		if (e <= s)
			return;
		
		int u = s, v = e;
		HashMap<String, Constant> x = list.get((s + e) / 2);
		
		while (v >= u) {
			while (isOK(list.get(u), x)) 
				u++;
			while (isOK(x, list.get(v)))
				v--;
			
			if (v >= u) {
				HashMap<String, Constant> temp = list.get(u);
				list.set(u, list.get(v));
				list.set(v, temp);
				v--;
				u++;
			}
		}
		
		sort(s, v);
		sort(u, e);
	}
	
	public void sort(boolean flag, String name) {
		
		this.flag = flag;
		this.name = name;
		
		sort(0, list.size() - 1);
	}
	
	
}